//
//  ReadMe.swift
//  YMWeiBo
//
//  Created by mimi on 16/7/19.
//  Copyright © 2016年 mimi. All rights reserved.
//

import Foundation
/*
 
 
 
 //每个文件的格式
 
 
 
 
 
 
 
 
 //        MARK: - =========== 响应事件 ===========
 
 
 
 
 
 
 
 func setupUI () {
 
 
 //        MARK: - 设置控件
 //1.添加控件
 
 
 
 
 //2.设置约束
 
 
 
 }
 
 
 
 
 //        MARK: - ==========  属性声明  =============
 
 
 
 
 
 
 
 
 
 //        MARK: -============= 懒加载控件 =============
 
 
 
 
 
 
 
 //
 //  ReadMe.swift
 //  01-公司开发介绍
 //
 //  Created by teacher on 16/7/19.
 //  Copyright © 2016年 teacher. All rights reserved.
 //
 /*
 - 上课版本
 - readMe 文件
 - 作用:
 - 把一些重要的东西记录说明下 便于后期我们在开发该项目能回忆起来
 - 为了你高薪飞 交接工作
 - 能叫大家清晰的知道我今天做了什么 便于你们晚自习复习
 
 
 
 =========================================================================
 - 第十一天
 - 创建20个表情按钮
 - 把表情按钮添加到数组中
 - 设置按钮的frame
 - 删除按钮 和frame
 - cell 中的字控件微调
 - pageView 给pageViewCell 赋值
 - 先把20个按钮全部隐藏
 - 遍历 模型一位数组 给button赋值
 - emoji表情
 - 图片表情
 - 添加pageControl
 - 使用kvc  currentPageImage  pageImage
 - 使用通知
 - 层级比较深  使用通知
 - emoji表情上屏
 - 图片表情上屏
 - 文本附件
 - 设置image
 - 设置bounds
 
 - 下午内容回顾
 - 发布微博
 - 文字微博
 - 图片&文字微博
 - 发布文字的时候 里面有图片表情
 - 遍历composeTextView 富文本
 - 当遍历到我们自定义的文本附件 得到其身上的emoticon
 - 通过的到chs
 - 把遍历的结果拼接字符串
 - 发送系统通知 隐藏或者显示占位问题
 - 强制调用代理方法 改变右侧按钮的状态
 - 使用RegexKitLite 遍历字符串 匹配我们的正则结果
 - 通过匹配到的结果 在单例中遍历一位数组 得到对象的emoticon
 
 
 
 =========================================================================
 - 第十天 表情键盘
 - 第十天内容回顾
 - 读取emoticon.bundle 文件
 - 读取plist文件
 - 字典转模型 得到一位数组
 - 通过 页数 做一位数组 转二维数组
 - 使用一位数组二维得到三维数组组
 - 使用三维数组 给表情键盘提供数据
 - 点击底部视图中的按钮 滚动pageView
 - 设置default按钮为选中状态
 - 滚动pageView  切换 底部视图按钮的选中状态
 - 注意 tag = 0  不要使用
 
 - 为什么使用bundle文件
 
 
 - 上午内容回顾
 - 通过监听系统通知 监听键盘将要该表frame
 - 监听 UIKeyboardFrameEndUserInfoKey y值
 - 更新底部视图的bottom约束
 - 自定义表情键盘
 - 使用textView.inputView
 - 判断 inputView 是否为nil
 - 判断是否是表情键盘 更改底部视图按钮的image
 - 自定义表情键盘中的底部视图
 - UIStackView
 - 不需要再给子控件设置约束 或者frame
 - 只支持 9.0 以上
 - 设置axis  排列方向
 - 设置distribution 填充方式
 - 初始化的时候 一定要加上frame
 - 通过addArrangedSubview 添加子空间
 - 添加按钮点击事件 闭包回调
 
 
 =========================================================================
 
 - 第九天 撰写动画
 - 下午内容回顾
 - 命名空间
 - 通过字符串获取class   类名.Type
 - class 传入的格式  "项目名.类名" 《自定义类》
 - uiimagepickerControler
 - 自定义配图cell
 - 添加背景图片
 - 添加删除按钮
 - 压缩图片 (通过等比例压缩   通过上下文 完成图片压缩)
 
 - 图片问题
 - 会引起内存暴涨
 - 会消耗用户流量
 - 会影响你上传图片的速度
 -解决办法
 - 图片压缩
 
 - 上传图片流程
 - 客户端上传图片
 - 压缩图片
 - 上传压缩后的图片到服务器
 - 通过客户端上传的图片
 - 01 保存原图
 - 02 通过自己的方式对客户端的上传的图片进行处理 变成高清图
 
 - 上午内容回顾
 - 自定义composeView
 - 截屏
 - 设置磨砂效果
 - 自定义button
 - 对imageView 和tilte 重新设置frame 和imageView & title的相关属性设置
 - 读取plist文件
 - 字典转模型
 - 遍历数组添加按钮
 - 给按钮设置动画
 - 通过第三方框架pop 动画
 
 - pop页面 分析
 - 贴在哪里 -> mainVc
 - 磨砂效果 怎么搞
 - 对当前屏幕截屏 获得image  然后通过苹果的分类搞定
 - 创建6个按钮 （因为image 和title 显示的位置不是默认的而且没有高亮效果, 需要自定义）
 
 
 
 =========================================================================
 
 - 第八天 时间格式化、发布微博界面
 - 回顾上午学习的内容
 - 微博来源
 - 使用字符串的截取
 - 富文本的使用
 - 底部视图
 - 转发 评论 赞
 - 字符串的替换
 - 微博时间格式化
 
 - 微博时间格式化处理
 
 - 如果是今年
 
 - 如果是今天
 - 小于60秒 显示 刚刚
 - 大于等于60秒且小于3600秒  显示 xx分钟前
 - 大于等于3600秒  显示  xx小时前
 
 - 如果是昨天
 - 例如 2016-07-25 10:10:10  显示格式 昨天 10:10
 
 - 如果是其他
 - 例如 2016-05-01 10:10:10  显示格式 05月01日 10:10
 
 - 如果不是今年
 - 例如 2015-01-01 10:10:10
 - 显示 格式: 2015年01月01日 10:10
 
 
 
 
 
 
 
 
 - 转发 评论 赞 业务逻辑处理
 - 如果count <= 0  显示 转发 评论 赞 例如 0  显示 转发 评论 赞
 - 如果count > 0
 - 如果 count < 10000  数据是多少显示多少  例如  8888  显示 8888
 - 如果 count >= 10000  显示 x.x万       例如 12000  显示 1.2 万
 - 注意 如果 count%10000 = 0  显示  例如 20000 显示 2万
 
 
 ==========================================================================
 - 第七天 配图和下拉刷新
 - 自定义下拉刷新控件分析
 - 自定义控件添加到tableView身上
 - frame = 0,-50,屏幕的宽度,50
 - 分析
 - 当用户拖动tableView 而且没有松手
 - 当contentOffset.y > -114 显示正常
 - 当contentOffset.y <= -114 下拉中
 - 当用户拖动tableView 而且松手了
 -  如果当前的状态为 下拉中   ---》刷新中
 
 - 上午内容回顾
 - 自定义配图 （collectionView）
 - 给status 添加一个属性 pic_urls 数组 需要程序员手动数组转模型数组
 - 通过外界给配图赋值 的数组.count  决定配图的size
 -col count == 4 ? 2 : count>=3 ? 3: count
 -row count == 4 ? 2 : (count -1)/3 + 1
 - 原创微博
 - 通过pic_urls.count 判断是否显示配图
 - 有配图
 - 没有配图
 - 系统cell
 - 自定义cell
 - 给cell赋值
 - bgImageView
 - gifImageView
 - 转发微博
 - retweet_status.pic_urls
 - 同原创微博相同
 - 抽取cell中常用间距
 
 
 ==========================================================================
 
 - 第六天 首页cell布局
 - 首页布局分析
 - 使用tableView显示
 - 由于是列表 每条微博数据 使用cell显示
 - 原创微博
 - 头像
 - 昵称
 - 会员等级
 - 认证
 - 微博发布时间
 - 微博来源
 - 微博内容
 - 配图(可能存在 可能不存在)
 
 - 转发微博 （可能存在, 可能不存在）
 - 微博内容
 - 配图(可能存在 可能不存在)
 
 - 底部视图
 - 转发按钮
 - 评论按钮
 - 赞按钮
 
 - 上午学习的内容回顾
 - 搭建UI
 - 请求首页数据
 - 01 使用网络工具类来请求（公共请求方法）
 - 02 把请求方法抽取到网络请求工具类中
 - 03 把请求抽取到StatusListViewModel
 - 创建模型
 - SHStatus
 - 自定义cell
 - 原创微博
 - 头像
 - 昵称
 - 微博等级
 - 时间
 - 来源
 - 认证
 - 微博内容未做
 - 创建SHUser
 - 由于系统不能给我们自定义的模型赋值
 - 重写setValueForKey 判断如果key == “user” 需要程序员手动赋值
 - 其他交给系统
 - 创建StatusViewModel(为cell服务 主要做数据处理)
 
 
 - ViewModel逻辑
 - homeVc -> statusListViewModel -> networkTools
 - statusList - > statusViewModel -> status -> cell
 - 今日内容总结
 - 请求首页数据
 - 抽取statusListViewModel
 - 创建模型
 - 搭建UI
 - cell分析(原创 转发 底部视图)
 - 开发原创视图
 - User
 - 抽取出一个statusViewModel
 - 对原创微博其他的控件赋值
 - 添加原创微博的正文
 - 底部视图
 - 转发微博
 
 ==========================================================================
 
 - 第五天 获取用户信息，界面跳转
 - 内容预告
 - 获取accessToken
 - 获取用户信息
 - 日期格式转换
 - 通过归档解档保存用户信息
 - 搭建欢迎界面
 - 使用通知切换根控制器
 - 搭建新特性界面
 - 判断是否是最新版本
 
 - 用户首次登陆
 - 访客视图界面
 - 调到微博登陆界面
 - 完成授权和保存数据后
 - 跳到欢迎界面
 
 - 当用户显示完欢迎界面后
 - 完成后显示MainVc
 - 关于根控制器确定
 - 如果用户已经登录  rootVc -> WelcomeVc
 - 如果用户没有登录  rootVc -> MainVc
 
 
 
 - 首次启动app
 - 判断用户是否登录
 - 如果登录了
 rootVc = WelComeVc
 - 如果没有登录
 rootVc = MainVc
 
 
 - 当用户没有登录
 - MainVc
 - 点击注册或者登录按钮 -> OAuthVc -> 完成授权和保存数据
 - 发送通知  显示WelComeVc
 - welComeVc 发送通知 把其当前的根控制器切换成MainVc
 - 当用户已经登录了
 - rootVc = WelComeVc
 - 当欢迎界面动画完成后 发送通知 切换根控制器为MainVc
 
 - 当用户进入新特性页面
 - 当用户滑动到最后一页
 - 点击button
 - 发送通知 切换根控制器 为MainVc
 
 - 判断版本
 - 为什么判断版本
 - 因为为了显示新特性页面
 - 什么时候会显示新特性界面
 - 如果用户已经登录了
 - 如果是新版本
 - rootVc = NewFeature
 - 如果不是新版本
 - rootVc = WelcomeVc
 - 如果用户没有登录
 - rootVc = MainVc
 
 
 - 第五天 下午内容回顾
 - 给ViewModel 中 添加 accessToken isLogin
 - 欢迎界面
 - 阻尼动画
 - 切换根控制器
 - 新特性页面
 - 阻尼动画
 - 切换根控制器
 - 判断app版本
 - 设置根控制器
 - 自定义搜索框
 
 
 ==========================================================================
 
 
 - 第四天
 - Extension的抽取
 - UIImageView
 - UILabel
 - Common 与OC中的pch文件相似
 - 屏幕的宽高
 - RGB颜色
 - 随机颜色
 - 主题颜色
 - 回顾OC单例
 - 学习了Swift单例的写法（与Swift中的懒加载相似）
 - 一共有两种写法
 - OC和Swift项目分别使用 对应的类
 - 如果OC中使用Swift的类
 - 格式 import "项目名-Swift.h"
 - 如果Swift中使用OC的类
 - 创建桥接文件  #import "OC类.h"
 - OC中 AFN 网络访问工具类的封装
 - Swift中的 AFN 网络访问工具类的封装
 - 网络请求公共的方法
 - 分别请求不同接口的方法
 - 作用
 - 便于后期维护管理
 - 把请求的urlString 和请求参数 均写在网络请求工具类中
 - OAuth授权
 - OAuth  open auth  开放的授权
 - 为什么使用该方式登录？
 - 如果一个公司开发一个app 使用手机号码完成注册登录 该公司可能没有职业道德
 - 泄露用户信息
 - 方便 微博账号 微信账号 等等
 - 公司大 认知度大
 - 模拟器 无法使用sdk 方式 为了给大家讲解 那么就需要使用OAuth
 - 我们做的一个是第三方的微博（山寨的）
 - 如果我们想使用微博的接口和数据 那么我们开发者就得遵守协议
 - OAuth授权
 - 01 需要开发者在微博开发者平台 注册一个账号 open.weibo.com
 - 02 需要注册为开发者 （个人开发者 公司开发者）
 - 03 在新浪微博开发者平台 注册一个应用
 - 只有注册完成 新浪微博会生成一个appKey appSecret （与人的身份证相似）
 - appKey 当前应用的id
 作用: 加载webView页面和请求其他接口需要
 - appSecret 请求接口需要
 - 需要开发者设置回调页
 -  加载webView页面和请求其他接口需要
 - 需要开发者设置测试账号
 - 当前的app为上架  但是开发者需要开发测试 就需要添加测试账号
 - 会加多个 (老板或者头或者产品经理)
 - 04 通过新浪微博提供的webView urlString 拼接appKey和回调页 加载授权界面
 - 05 用户使用中 输入用户名和密码 点击确定
 - 06 点击授权按钮  完成授权
 - 07 得到微博服务器返回的code （授权码）
 - 08 通过上面的相关信息 获取 accessToken
 - 09 通过accessToken  获取个人信息和访问其他接口
 
 
 - 关于注册问题
 - 注册
 - 01  http://www.baidu.com?company="xxxx"&手机号=12345678&密码=1234567
 - 如果请求成功 服务器 userid name 相关信息 表示出当前用户是使用手机注册
 - 02  http://www.baidu.com?company="open"&userid=xxx&name="xxx"&sex="0"&age="18" 表示当前用户使用第三方信息完成注册
 
 - 第四天内容回顾
 - 搭建OAuth界面
 - OAuth授权
 
 - 登录开发者平台
 - 注册一个应用
 - 得到appKey appSecret 回调页
 - 设置回调页
 - 添加测试账号
 - 加载webView 页面
 - 通过webView 代理方法 得到code （code的截取）
 
 
 ==========================================================================
 
 
 
 - 第三天 项目阶段
 
 - 公司组织开发架构
 - 客户 -> 甲方
 - 老板 -> 乙方
 - 开发部们
 - 技术总监
 - 移动端开发
 - 苹果
 - 安卓
 - H5
 - PC端开发
 - JAVA
 - PHP
 - .NET
 - 后台开发
 - JAVA
 - PHP
 - .NET
 - 产品
 - 产品经理
 - 产品专员
 - UI
 - UI妹子 UI汉子
 - 测试
 - 难缠
 - 运营部 营销 或者推广
 
 - 一个app的诞生
 - 从无到有的过程
 - 新组建的团队
 - 甲方或者老板提出需求
 - 技术总监和产品经理 把甲方或者老板的想法前期可能就是一张A4
 - 产品经理 出原型
 - 技术研讨会
 - 看原型产品实施性
 - UI妹子 出效果图 标注图
 - 移动端 搭建框架
 - 服务器 模拟数据
 - 移动端和服务器
 - code  0 成功 1 代表失败
 {
 code
 message
 data
 }
 - 紧急会议
 - 开发遇到问题 可能需要砍掉功能或者换种方式实现
 - 测试人员测试
 - 封板
 - 发布审核上线
 - 代码优化 版本迭代
 
 
 - 开发工具(团队开发)
 
 - bug处理
 - JIRA
 - bugfree
 - 代码管理
 - SVN
 - git
 - 自己搭建git服务器
 - 码云 天朝 （支持国货）
 - 优点 中文
 -创建私有项目免费
 - 服务器在中国
 - github
 - 缺点: 收费 讨厌
 - 创建私有项目收费
 - 两种代码管理方式
 - HTTPS
 - 不需要生成公钥和秘钥
 - 不安全 每次输入用户名密码 造成代码丢失
 - SSH
 - 安全
 - HTTPS的缺点就是他的优点
 
 - 讲解
 - RSA 密钥  非对称加密 加密效率低
 - AES 秘钥  对称加密  加密效率高
 - 流程
 - 生成一个私钥和公钥
 - 把公钥非服务器
 - 随机生成一个AES秘钥
 - 通过私钥对AES秘钥加密
 - 把加密后的AES秘钥发送到服务器
 - 通过AES秘钥对项目加密
 - 服务器拿到加密后的AES秘钥 通过公钥解密
 - 服务器接收到通过AES加密后的项目
 - 服务器拿到解密后的AES 对加密的项目进行解密
 - 服务器帮我们保存项目
 
 - 项目开发
 - 模块确定
 - 首页
 - 消息
 - 发现
 - 我
 - MVVM
 - Model
 - View (view 和 VC)
 - ViewModel
 - 帮助Vc减压
 - 帮助view减压
 - 上午内容回顾
 - 码云的使用
 - SSH
 - 需要程序员生成公钥和私钥
 - 在码云中创建一个项目
 - 克隆项目
 - 添加忽略文件
 - 项目框架
 - 最低支持版本
 - 类前缀
 - 设置横竖屏
 - 设置图标 启动页
 - 删除main.sb
 - 创建项目文件夹
 - Main
 - Home
 - Message
 - Discover
 - Profile
 - UIImageRenderingMode 图片渲染方式
 - TintColor
 - git冲突问题
 - 团队开发
 - 有一份代码
 - A
 - B
 - 关于访客视图
 - 如果用户没有登录 四个子控制器 显示的为访客视图
 - 如果用户已经登录 四个子控制器 显示的列表
 - 解决方式 创建一个基类 其他四个子类继承基类
 
 - 第三天内容总结
 - 搭建框架
 - 添加子控制器
 - 创建基类 （程序员偷懒）
 - 自定义visitorView
 - SnapKit的使用
 - 定义一个公共方法 供外界调用完成不同视图显示信息不同
 - 设置圆圈动画
 - Swift中 代理和协议的使用
 - 使用闭包
 - 自定义tabbar
 - 添加撰写按钮
 - 通过遍历子控件完成控件布局
 - 使用闭包
 - 自定义UIBarButtonItem
 - Extension中使用便利构造函数
 - 自定义SHBarButtonItem 使用重载构造函数
 
 */
 
 
 
 
 
 
 
 
 
 
 
 
 
 */